/*
 * Copyright (c) 2011-2012 Tygron Serious Gaming
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'Swing to Nifty Converter' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package nl.tygron.niftyconverter;

import java.awt.Component;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JViewport;
import nl.tygron.niftyconverter.converters.ButtonConverter;
import nl.tygron.niftyconverter.converters.CheckBoxConverter;
import nl.tygron.niftyconverter.converters.ComponentConverter;
import nl.tygron.niftyconverter.converters.ContainerConverter;
import nl.tygron.niftyconverter.converters.DropDownConverter;
import nl.tygron.niftyconverter.converters.LabelConverter;
import nl.tygron.niftyconverter.converters.ListConverter;
import nl.tygron.niftyconverter.converters.PanelConverter;
import nl.tygron.niftyconverter.converters.ProgressBarConverter;
import nl.tygron.niftyconverter.converters.ScrollPaneConverter;
import nl.tygron.niftyconverter.converters.SliderConverter;
import nl.tygron.niftyconverter.converters.TextAreaConverter;
import nl.tygron.niftyconverter.converters.TextFieldConverter;
import nl.tygron.niftyconverter.elements.NElement;
import nl.tygron.niftyconverter.elements.NLayerElement;
import nl.tygron.niftyconverter.elements.NScreenElement;
import nl.tygron.niftyconverter.elements.NiftyStructure;
import nl.tygron.niftyconverter.elements.NiftyXMLRootElement;

/**
 * @author Jeroen Warmerdam, Raymond Weijermars
 * @Specialism GUI
 * @Maintainer Jeroen Warmerdam
 */
public class UIConverterDatabase {

	// private static final Logger logger = Logger.getLogger(UIConverterDatabase.class.getName());

	private final ImageDatabase dbase;
	private final Map<Class<? extends Component>, ComponentConverter> converterMap = new HashMap<Class<? extends Component>, ComponentConverter>();

	public UIConverterDatabase() {

		this.dbase = new ImageDatabase();

		converterMap.put(JPanel.class, new PanelConverter(dbase));
		converterMap.put(JViewport.class, new ContainerConverter(dbase));
		converterMap.put(JButton.class, new ButtonConverter(dbase));
		converterMap.put(JScrollPane.class, new ScrollPaneConverter(dbase));
		converterMap.put(JLabel.class, new LabelConverter(dbase));
		converterMap.put(JSlider.class, new SliderConverter(dbase));
		converterMap.put(JList.class, new ListConverter(dbase));
		converterMap.put(JCheckBox.class, new CheckBoxConverter(dbase));
		converterMap.put(JComboBox.class, new DropDownConverter(dbase));
		converterMap.put(JTextArea.class, new TextAreaConverter(dbase));
		converterMap.put(JTextField.class, new TextFieldConverter(dbase));
		converterMap.put(JProgressBar.class, new ProgressBarConverter(dbase));

	}

	public NiftyStructure convertScreen(Component screenComponent, NiftyStructure nStructure, Component topMostObject) {

		NiftyXMLRootElement root = (NiftyXMLRootElement) nStructure.getRootElement();
		NScreenElement screenElem = new NScreenElement(topMostObject.getClass().getSimpleName(), nStructure);

		NLayerElement layerElem = new NLayerElement("layer", nStructure); // TODO: Ray, shouldn't hardcode names!!

		root.addChild(screenElem);
		screenElem.addChild(layerElem);

		retrieveComponents(screenComponent, layerElem, nStructure, topMostObject);

		return nStructure;
	}

	public void retrieveComponents(Component comp, NElement parent, NiftyStructure nStructure, Component topMostObject) {

		Class<? extends Component> componentClass = comp.getClass();

		// This is to ensure that every non-java swing component is treated as a panel
		if (!componentClass.getPackage().getName().contains("javax.swing")) {
			componentClass = JPanel.class;
		}

		if (componentClass.equals(JTextArea.class)) {
			if (((JTextArea) comp).isEditable()) {
				componentClass = JTextField.class;
			}
		}

		ComponentConverter converter = converterMap.get(componentClass);

		if (converter == null) {
			return;
		} else if (!converter.isOnlyCheckContainer()) {

			NElement nElement = converter.convert(comp, nStructure, this, topMostObject);

			if (nElement != null) {
				if (parent == null) {
					nStructure.setRootElement(nElement);
				} else {
					parent.addChild(nElement);
				}
			}
		} else {
			converter.onlyCheckContainer(parent, comp, nStructure, this, topMostObject);
		}

	}

}
